从最开始的使用img图片,到后来的使用css sprite来减少服务器请求,再到流行的图形字体化图标Iconfont。现在,一种全新的图标使用方式开始流行了起来——SVG symbols图标。
工作原理
SVG symbols的工作原理:symbol元素用来定义一个图形模板对象,它可以用一个use元素实例化。
symbol元素对图形的作用是在同一文档中多次使用,symbol元素本身是不呈现的。只有symbol元素的实例(亦即,一个引用了symbol的use元素)才能呈现:
1 | <svg> |
这段代码使用SVG symbols定义了两个图标,每个symbol元素定义一个图标,图标id分别是heart和arrow,将其放在html文件的body元素内。
通过以下代码引用id为heart的图标:
1 | <svg> |
xlink:href属性值就是‘#’加symbol的id名称,那么只需改变这个属性值就可以引用不同的图标。
gulp自动化处理
如果你使用gulp构建项目,推荐使用一个专门用于处理SVG Symbols用的glup插件gulp-svg-symbols,它不但能生成SVG Symbols文件,还能生成一个demo文件方便查看图标和复制代码。
安装gulp-svg-symbols插件,若没有预先安装gulp请先行安装:
1 | npm install gulp-svg-symbols --save-dev |
gulpfile.js写入如下执行任务:
1 | const gulp = require('gulp') |
现在生成SVG symbols文件了,那怎么将它引入到页面呢?如果是多页应用推荐使用svg4everybody.js为所有浏览器添加了SVG外部内容支持。这样就能直接使用外部的SVG symbols文件。
在文档中包含该脚本:
1 | <script src="/path/to/svg4everybody.js"></script> |
使用外部的SVG symbols文件时,通过以下代码引用图标(map.svg是外部的SVG symbols文件,codepen是图标id):
1 | <svg> |
如果是单页应用,使用svg4everybody.js就感觉太繁琐了,能不能一步搞定啊?当然可以,将将SVG symbols文件转成js文件就好了,推荐使用gulp-svg-symbols2js将SVG symbols文件转成js文件。
安装gulp-svg-symbols2js插件:
1 | npm install gulp-svg-symbols2js --save-dev |
修改gulpfile.js文件:
1 | const gulp = require('gulp') |
现在只要引入生成的js文件,就可以在页面中使用以下代码引用图标:
1 | <svg> |
webpack自动化处理
如果你的项目使用webpack进行打包,可以考虑使用svg-sprite-loader插件自动生成SVG symbols文件。
安装svg-sprite-loader:
1 | npm install svg-sprite-loader --save-dev |
将svg图标放到src/icons目录下,在webpack配置文件中添加svg-sprite-loader的配置:
1 | const path = require('path'); |
在打包文件(index.js)中引入单个图标:
1 | import cloud from './icons/cloud.svg' |
这样引入的好处是只引入需要的图标,没引入的图标不会被打包,缺点是当图标很多时这样引入会显得很繁琐,因为一般情况下,所有图标都会被使用,所以有必要找到一种简单的方式一次引入所有图标。
使用一些代码将svg图标全部引入:
1 | const requireAll = requireContext => requireContext.keys().map(requireContext); |
现在可以在HTML中使用图标了:
1 | <svg> |
经验总结和建议
- 始终使用gulp构建,方便浏览的图标demo在开发中很重要
- 始终使用单色图标,多色图标只能通过id选择器修改样式
- 始终在ie9+,及现代浏览器使用,传统浏览器使用iconfont更好